home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ARASAN_S.ZIP / README < prev    next >
Text File  |  1994-08-15  |  29KB  |  583 lines

  1.         Arasan - Chess for Windows - version 1.2
  2.             Programmer's Guide
  3.  
  4.                by Jon Dart
  5.  
  6. Arasan is a chess program for Windows 3.1.  It is copyrighted
  7. but under terms that allow free distribution for non-commercial
  8. purposes.
  9.  
  10. This archive contains the source code for Arasan. I am providing
  11. the source code for the use of programmers who may wish to
  12. understand how the program works or to modify it for their own use.
  13. However, you may not distribute a modified version of this program
  14. without the consent of the original author.
  15.  
  16. Arasan is written in C++ and was compiled with the Borland C++
  17. compiler, version 4.0 (the source can also be compiled under
  18. Borland C++ version 3.1).  Arasan uses the Windows++ class library
  19. by Paul DiLascia.  Source for Windows++ is not included in this
  20. distribution.  It is available for $25 from:
  21.  
  22.      Paul DiLascia
  23.      P.O. Box 391632
  24.      Cambridge, MA 02139
  25.  
  26. Note: I have no connection with Paul DiLascia.  I am just a user of
  27. his library.  In a future version of Arasan I hope to convert to using
  28. a different, more widely available class library such as MFC or OWL.
  29. I have made a few bug fixes in the Windows++ source code; see the
  30. file WPP.DIF for details of what was changed.
  31.  
  32. The remainder of this file contains information for use by programmers
  33. reading or working on Arasan source code.  I assume that you have a 
  34. working familiarity with C++, Windows programming, and the Borland
  35. compiler and tools.
  36.  
  37. Building Arasan
  38.  
  39. I have attempted to make the source code for Arasan as portable as
  40. possible, but I don't guarantee that it can be built with
  41. any compiler except Borland C++.  In particular, since it uses
  42. templates, it cannot be compiled with Microsoft Visual C++ 1.0
  43. or 1.5.
  44.  
  45. To compile Arasan, first edit the "make.cfg" file so that BCCDIR
  46. points to your installation of Borland C++, and WPPDIR points to your
  47. installation of Windows++.  If you are using Borland C++ 3.1, you
  48. will need to remove the -x- switch from the CFLAGS variable defined
  49. in this file.
  50.  
  51. Then just type "make" from the source directory.  Make will compile
  52. and link the executable (arasan.exe).  I recommend that you have a
  53. minimum of 4 Megabytes of memory in order to build the source.  If
  54. you are compiling in a DOS box and run out of memory, try exiting
  55. Windows and running "make" from DOS.
  56.  
  57. Opening book format
  58.  
  59. The opening book for Arasan is composed of two binary files, one for the
  60. White moves ("BOOKW") and one for the black moves ("BOOKB").  At build
  61. time, these files are bound into the executable by the resource compiler.
  62. The format of the binary files is documented in makebook.cpp.
  63.  
  64. Since BOOKB and BOOKW are supplied with the source, you don't need to
  65. create these files in order to build Arasan.  However, if you want to
  66. modify the contents of the opening book, you will need to edit the ASCII
  67. source for the openings and rebuild BOOKB and BOOKW.  Following is
  68. information on how to do this.
  69.  
  70. The ASCII source for the opening book is contained in the file BOOK.TXT.
  71. Moves are listed one or more per line in standard algebraic notation.
  72.  
  73. A move may optionally be followed by a number from 0 to 9.  The
  74. number, if given, is the "weight" assigned to the move.  A weight of
  75. 0 means that the computer will never play the move, but will respond
  76. to it if it is played by its opponent.  However, if a weight of 0 is
  77. specified after a non-zero weight for the same move in the same
  78. position has already been specified, the original weight is
  79. unchanged.
  80.  
  81. The higher the weight, the more often the computer will choose the
  82. move compared to the other alternatives in the book.  By default, if
  83. no weight is specified, a weight of 5 is assigned.  The supplied book
  84. uses weights rather sparingly.  In general, the computer has been
  85. steered away from gambits, and away from openings it doesn't play
  86. well.  It is also biased towards playing the main line of an opening
  87. as opposed to less common variants.  Note: I am not a strong player,
  88. and so the opening book is probably far from optimal.  It is also not
  89. very extensive: currently it contains aroud 10000 half-moves, mostly
  90. from recent grandmaster games.  Suggestions for expansion and/or
  91. improvement of the opening book are quite welcome.
  92.  
  93. Some special symbols are allowed in the opening book.  Any line
  94. beginning with ";" is treated as a comment and ignored.  An "m" in
  95. the first column means that the present position should be
  96. remembered.  An "r" in the first column restores the position to
  97. where it was when the last "m" was encountered.  This allows easy
  98. entry of variant lines from the same starting position.  Only one
  99. remembered position can be stored and retrieved, however: e.g. if you
  100. specify "m" twice, the first position stored is discarded.
  101.  
  102. Building the opening book
  103.  
  104. To build the binary opening files from BOOK.TXT, you first need to
  105. build the program MAKEBOOK.EXE.  To do this, type "make -f
  106. makebook.mak".  MAKEBOOK is a DOS program that uses some of the same
  107. files as the chess program.  Since it must be built for DOS and not
  108. Windows, make sure you remove any old object files before building
  109. it, so that you don't get Windows objects mixed in with the DOS
  110. objects.
  111.  
  112. Once MAKEBOOK has been built, just execute it and it will read BOOK.TXT
  113. and produce BOOKB and BOOKW.  Error messages are issued if any moves
  114. are illegal or if there are syntax errors in the input file.
  115.  
  116. Testing support
  117.  
  118. Arasan includes several features to aid debugging.  If you compile the
  119. source with -DRANGE_CHECK, checks are inserted for accessing arrays
  120. past their boundaries, as well as some other sanity checks.  If any
  121. of these checks fail, an error box will be displayed with the assertion
  122. that failed.
  123.  
  124. For debugging purposes, it is also possible to build a DOS executable
  125. that contains the Arasan search engine, but no user interface.  This
  126. executable is called "TESTSRC".  To build TESTSRC, do "make -f testsrc.mak".
  127. Since testsrc is a DOS executable but uses many of the same files as the
  128. Windows executable, be sure to delete any old object files before building
  129. TESTSRC.  "make clean" will do this.
  130.  
  131. TESTSRC takes a command line that consists of one of two optional
  132. switches followed by an optional filename.  The two allowable
  133. switches are:
  134.  
  135. -p <number> - performs a fixed-ply search to the indicated depth.
  136. -t <number> - searches for the given number of seconds.
  137.  
  138. The filename, if specified, contains one or more board positions to be
  139. analyzed, one per line.  The position info is in EPD (Extended
  140. Position Description) format.  TESTSRC currently only recognizes a
  141. small subset of EPD, sufficient to run the tests.
  142.  
  143. If the search module is compiled with -DTRACE, TESTSRC will print out
  144. copious information about the search process when it is run.  See
  145. search.cpp to see what information is output and where it comes from.
  146. Another compile-time debugging option is -DDEBUG_ATTACKS, which will
  147. insert test code to check that the attack information for the board
  148. is updated correctly when a move is made.
  149.  
  150. Because TESTSRC is a DOS program, it can easily be run from a batch
  151. file to execute a series of tests.  The following test suites are
  152. provided with the source code (see the TESTS directory):
  153.  
  154. 1. TESTS.EPD contains 22 fairly simple tactical problems.  Arasan
  155. should solve all these problems with a nominal 3-ply search.
  156.  
  157. 2. WAC.EPD contains the 300 problems from Reinfeld's "Win At Chess"
  158. book.  These are mostly easy tactical problems.  Arasan solves about
  159. 2/3 of them with a 60-second search limit on a Pentium 60.
  160.  
  161. 3. The file BK.EPD contain the Bratko-Kopec series of tests.  It is
  162. standard procedure to allow the program 2 minutes for each test.
  163. Some of these problems are quite difficult.  Arasan currently solves
  164. 11 out of the 24 problems when run on a 60MHz Pentium.
  165.  
  166. 4. The file ECE3100.EPD contains the first 100 problems from
  167. Encyclopedia of Chess Endgames, volume 3.  These are rook endgames.
  168.  
  169. 5. Another endgame test suite is FINE.EPD, containing 48 king and
  170. pawn endgame problems from Reuben Fine's Basic Chess Endings.
  171.  
  172. 6. TYPP.EPD contains tests from Bellin and Ponzetto's book Test
  173. Your Positional Play.
  174.  
  175. 7. ECM.EPD contains test positions from the Encyclopedia of Chess
  176. Middlegames.  These are difficult middlegame problems.
  177.  
  178. The RESULTS file in the TESTS directory summarizes Arasan's performance
  179. on these test suites.  Details of the test runs can be found in the log
  180. files, e.g. TESTS.LOG, BK.LOG, etc., which are also in the TESTS
  181. directory.
  182.  
  183.  
  184. Algorithms and data structures
  185.  
  186. 1. The chess board
  187.  
  188. Following is some information about the algorithms and data
  189. structures used by Arasan.  If you are new to computer chess
  190. programming, I suggest first reading a general work on the
  191. subject such as Frey (1983) or Marsland and Schaeffer (1990).
  192.  
  193. The chess board in Arasan is represented by an array of 64 squares.
  194. Each square contains 0 if it is empty, or a piece identifier if it is
  195. occupied.  Black pieces have identifier values between 1 and 6, while
  196. White pieces have values between 9 and 15.  (Note: the program used
  197. to use a variant of the "mailbox" representation described by Frey,
  198. with 120 squares.  This allows easy detection of when a piece has
  199. reached the board boundary.  However, because stack space is a
  200. limited resource in Windows, the representation was changed to use
  201. only 64 squares).  A special value (127) is used to represent a
  202. square that is uninitialized or invalid.
  203.  
  204. The Board class also maintains a parallel board representation called
  205. "PiecePos" consisting of two arrays of 16 entries each.  These contain
  206. lists of the squares occupied by pieces of each side.  Any array
  207. entry unoccupied by a piece is set to 127.
  208.  
  209. Several other pieces of information are stored in the Board class and
  210. are updated for each move.  The KingPos array holds the location of
  211. each side's king.  The PFileCount array holds a count of the number
  212. of pawns on each file, for each side, and the RFileCount array holds
  213. a similar value for rooks.  The EnPassantSq array holds the square
  214. position, for each side, on which an en passant capture is possible
  215. (obviously, only the side to move can have a possible en passant
  216. capture, but we maintain two values for programming convenience).
  217. The CastleStatus array holds an enum for each side indicating whether
  218. castling has occurred.  Also, if the king or a rook has been moved,
  219. making castling on one side or another impossible, CastleStatus is
  220. set to an appropriate value.
  221.  
  222. Each board position also has a hash code associated with it.  The
  223. hash code is 32 bits and is computed by fetching, for each piece and
  224. square combination, a unique 32-bit code from a table of random
  225. numbers, and computing the exclusive or of these codes.  The
  226. low-order bit of the hash code is then set to identify whether White
  227. or Black is to move.  Castling status and en passant status are not
  228. folded into the hash code, but are stored in a separate field in a
  229. hash table entry - they must match the current board in order
  230. for a position to be retrieved from the table.
  231.  
  232. Finally, the board position includes an array, for each side, of type
  233. Attacks.  This contains an integer for each square indicating which
  234. pieces and of what kinds attack the square.  This information is
  235. incrementally updated (by the Attacks class) when a move is made or
  236. unmade.  Attacks does not store information about "stacked"
  237. attackers, which may make some calculations involving this
  238. information inaccurate.
  239.  
  240. An earlier chess program I wrote re-calculated complete attack
  241. information for each position that was evaluated, but it wound up
  242. spending a large fraction of its time in the attack calculation
  243. procedure.  Incrementally updating the attack information is
  244. relatively cheap and probably faster.
  245.  
  246. 2. Moves
  247.  
  248. There are three move classes used in Arasan.  "Move" maintains only
  249. the minimal information need to unambiguously specify a move: start
  250. square, destination square, and promotion value.  "ExtendedMove"
  251. contains also the piece being moved, the piece being captured (if
  252. any), and the type of move (normal, castling, en passant, etc).
  253. Finally, "ReversibleMove" contains in addition the castling and en
  254. passant status of the board before the move was made.  Since this
  255. information is needed for restoring the board position, only a
  256. ReversibleMove can be "undone".
  257.  
  258. 3. Move Generator
  259.  
  260. The move generation logic is mostly contained in the classes Bearing,
  261. Move_Generator and Move_Ordering.  Bearing contains static functions
  262. to compute squares to which a piece can move.  Except for pawn moves,
  263. and for castling, move generation is done by table lookup.  Each
  264. class of piece has an associated table.  Each table is indexed by
  265. square number and side to move, and contains a list of squares to
  266. which the piece could move (these tables are in beardata.h).
  267. Additional checks are made to see that the destination square doesn't
  268. contain a piece of the same color.  However, moves into check are
  269. possibly included.
  270.  
  271. The Move_Generation class uses functions from Bearing to generate all
  272. moves for a given side.  Moves into check are included, unless the
  273. side to move is in check.  In that case, a special function
  274. (Check_Evasions) is called that strictly checks moves for equality.
  275. It is very important to know whether any legal moves are possible
  276. when in check: if there are none, the side to move is checkmated.
  277. Also, some search extensions depend on the existence of a forced move
  278. (one single legal move).
  279.  
  280. Move_Generation also calls the Move_Ordering class to re-order the
  281. moves.  At ply 0, some rather elaborate criteria are used for move
  282. ordering: this includes a computation of each moves' positional
  283. score, and also (for captures), a call to function attack_estimate,
  284. which uses the attack information for the destination square to
  285. estimate the gain from a capture.  At ply 0, all moves are scored and
  286. sorted.  At higher plies, a less elaborate algorithm is used, which
  287. moves the first few most promising moves to the start of the move
  288. array, and then sorts only those.  Captures are given a high priority
  289. in the search order - higher if the capture appears to gain material,
  290. but fairly high even if the capture apparently loses.  Promotions are
  291. also given special treatment.
  292.  
  293. Arasan also uses the "killer" heuristic.  Moves that cause beta
  294. cutoff in the search are stored in a killer array, and the move
  295. ordering routine will give these moves a higher score than other
  296. moves.  But captures are generally given a higher score than "killer"
  297. moves, so the killer moves have a relatively small effect on the
  298. overall move ordering.  The scoring algorithms in Move_Ordering have
  299. been tuned to maximize search speed, mostly on the tactical problems
  300. in the test suite, but there is doubtless more room for improvement.
  301.  
  302. 4. Searching
  303.  
  304. Arasan uses an alpha-beta search algorithm with a variety of search
  305. extensions.  The search class is the largest single module in the
  306. program, and is necessarily rather complicated, but I have tried to
  307. structure it and comment it so that it is understandable.  I will
  308. assume that the reader knows the basics of the alpha-beta algorithm,
  309. and will concentrate on describing this implementation of it. 
  310.  
  311. In general, the search routine tries to terminate a search tree, or
  312. some portion of one, as soon as possible, and will defer as much work
  313. as possible until it is certain that no early and quicker termination
  314. can be done.  The techniques for doing this are mostly well-known and
  315. there is nothing very original about the search algorithms used by
  316. Arasan.  However, as with most chess programs, there is a fine
  317. balance between terminating a search too soon and extending it into
  318. unprofitable and very unlikely lines of play.  The precise nature of
  319. this balance depends not only on the search algorithms used, but also
  320. the relative efficiency of operations such as move generation,
  321. position evaluation and move ordering.  Each program therefore
  322. strikes this balance in a somewhat different way.
  323.  
  324. The entry point for a search is a routine called find_best_move.
  325. This function does some initialization, and then calls move_search,
  326. which implements the alpha-beta search algorithm.  The search
  327. proceeds one ply (half move, i.e. move by one side) at a time.  That
  328. is, first a one-ply search is done, then a two-ply search, then
  329. three, etc. until either the maximum ply limit has been reached or
  330. the time control has been exceeded.  Each search uses the results of
  331. the preceeding search.  The variable "max_depth" holds the current
  332. nominal ply depth for the search.  However, the presence of search
  333. extensions means that some nodes may be searched to a greater depth
  334. than this.
  335.  
  336. The first step in move_search is to look in the hash table (further
  337. described in the next section), in order to see if an identical
  338. position has been visited before.  This may happen due to a
  339. transposition of moves that lead to the same position, or because a
  340. previous search to a shallower depth visited the same node.  If a
  341. hash table entry is found and if it contains a valid value (i.e. one
  342. that did not cause cutoff), then that value is returned immediately
  343. and no further searching from that node occurs.  In other cases, the
  344. hash table may not contain an exact value, but may hold an upper or
  345. lower bound that can be used to narrow the alpha-beta window.
  346.  
  347. After the hash table check, a further check is made to see if the current
  348. board position is drawn, due to insufficient material or to a 3-fold
  349. repetition of moves.  Arasan does not currently check for draws due to
  350. the 50-move rule or variants of it.
  351.  
  352. If the position is drawn, move_search returns the negative of the
  353. evaluation function.  This penalizes the program for allowing a draw
  354. when it is ahead in material or has a superior position.
  355.  
  356. If the search has reached the nominal search depth plus the maximum
  357. possible search extension depth, or exceeded the maximum supported
  358. ply depth, it also terminates immediately.
  359.  
  360. Normally the initial score for the position is set to -Constants::BIG
  361. (BIG is a large integer used several places in the search process).
  362. However, a different approach is taken when pursuing search
  363. extensions, i.e. portions of the search tree beyond the nominal
  364. search depth (max_depth).  Three different types of search extension
  365. are used in Arasan:
  366.  
  367. a. If the side to move is not in check, and if the search exceeds the
  368. maximum depth, searching continues but includes only promotions and
  369. capture moves that appear to gain material.  There is a limit, set in
  370. the Extensions structure, to how many additional plies may be
  371. searched.
  372.  
  373. b. If the side to move is in check, the search is also extended, and
  374. includes all legal replies, again up to the limit set in Extensions.
  375.  
  376. c. Finally, forced moves (moves with only one possible reply) cause
  377. the search to be extended one ply and this ply is not counted towards
  378. the computation of any other search limit.
  379.  
  380. In case a., which in the source code is called a "capture search,"
  381. the current position is evaluated and searching may terminate if the
  382. resulting value causes beta cutoff.  The reasoning is that there is
  383. no point continuing the search if the side to move can "stand pat"
  384. without making any furture captures, and still obtain a value high
  385. enough for cutoff.  However, this early cutoff is inhibited if the
  386. side to move has an apparently trapped piece, or appears to have
  387. a "hung" piece (a piece subject to profitable capture).
  388.  
  389. If early cutoff doesn't occur, the next step is to try the "null
  390. move.".  The side to move is changed without altering the board
  391. position and the opposing side is then allowed to move.  Of course,
  392. this could not occur in a game - a player is not allowed to "pass,"
  393. but must move.  However, the theory is that if the null move causes
  394. cutoff, then the side to move must have a good position, since in
  395. effect giving the opponent a free move still produces a high value
  396. for the side to move.  In this case, beta cutoff is allowed to occur
  397. and no more searching is done from this node.  This search
  398. enhancement is enabled by compiling with -DNULL_MOVE.
  399.  
  400. If the null move does not cause cutoff, then the principal variation
  401. move is searched.  In the case of an initial search (e.g. a one-ply
  402. search), the principal variation move is just the first move returned
  403. by the move generator.  Otherwise, at ply 0, it is the
  404. highest-scoring move from the previous search iteration.  This is
  405. obtained by sorting the 0-ply moves from the last iteration, all of
  406. which were stored along with their scores.  At deeper plies, the hash
  407. table is queried and if a best move has been stored for the position,
  408. that move is tried first and is considered the principal variation.
  409.  
  410. The search first calls skip_move to see if the move should be
  411. skipped.  skip_move enforces the search extension limits mentioned
  412. above.  If the move is not to be skipped, skip_move returns "False",
  413. and the search proceeds to call try_move.  try_move will first make
  414. the move, then query the attack info for the board to see if the side
  415. to move is in check (remember, the move generator typically does not
  416. exclude moves into check).  If a move into check is found, the
  417. special value Illegal is returned and the next move is tried.  If the
  418. move passes the legality check, then move_search is called again (it
  419. is thus indirectly recursive).
  420.  
  421. If the return value from move_search did not cause cutoff, then the
  422. search must be peformed again with a wider search window.  try_move
  423. takes care of this.  try_move also checks the timer (if a timed search
  424. is being done) and determines when to terminate the search.  Usually
  425. this occurs when 95% of the allotted time has been used, but in some
  426. cases the computer will be allowed to search a slightly longer time.
  427.  
  428. Once try_move returns a value for the node, it is compared against
  429. alpha and beta.  If the value exceeds alpha, then a new best move has
  430. been found at this node and the move is stored.  If the value exceeds
  431. beta, cutoff occurs and no more searching is done.  A special check
  432. is also made to see if the value indicates that mate has occurred,
  433. since there is no point searching any further after that.
  434.  
  435. Assuming the principal variation move does not cause cutoff or mate,
  436. then move_search proceeds to search the remainder of the moves.
  437. These are searched with a minimal alpha-beta window.  Note that since
  438. the principal variation move is usually obtained from the hash table
  439. or the ply0moves array, it may be the case that the move generator
  440. has never had to be called before now.  If so, we call it at this
  441. time.  An earlier version of Arasan tried to optimize things further
  442. by only generating part of the moves at a time.  That way, if cutoff
  443. occurred, the remainder of the move generation could be skipped.
  444. However, there was a cost to this in terms of complexity and it did
  445. not seem to help search speed much.
  446.  
  447. The final part of move_search checks to see if checkmate or stalemate
  448. occurred, and updates the hash table.
  449.  
  450. When the top-level invocation of move_search terminates, it returns
  451. to find_best_move, which determines the time used, and updates the
  452. "Statistics" structure with the time and other information about the
  453. search.
  454.  
  455. 5. The hash table
  456.  
  457. The search routine uses a hash table for storing the results of
  458. evaluating previously visited positions.  This table is implemented
  459. using a template class (Hash) because the opening book generator uses
  460. a similar hash table but stores somewhat different information in the
  461. table.  The hash table is basically an array of lists (class S_List).
  462. Each list contains a series of nodes (S_Node), each of which contains
  463. some data (in the case of the search engine, a class of type
  464. Position_Info) and a pointer to the next node.  Each list holds
  465. entries that hash, modulo the hash table size, to the same value.
  466. Each node contains the whole hash code, so that finding a given node
  467. to match a given hash code consists of indexing into the hash table,
  468. then following the list until the hash codes match.
  469.  
  470. Besides the hash code, each hash entry also contains the score for
  471. the node, a set of flags indicating whether the value is exact, an
  472. upper bound or a lower bound, the depth of search used to evaluate
  473. the node, a word holding the castling status and en passant square,
  474. and the best move for the position.
  475.  
  476. Under Windows, the number of lists in the hash table is configured
  477. at runtime based on the amount of memory available.  Under DOS,
  478. the number of lists is fixed in size.  In both cases, there is also
  479. a limit on how many nodes can be entered into the table.  The hash
  480. table is cleared after each search.
  481.  
  482. Memory allocation and deallocation for the hash table can be quite
  483. expensive, especially under Windows.  To minimize this, operators
  484. new and delete are overloaded for both S_List and S_Node classes.
  485. These operators use a simple memory allocation scheme that obtains
  486. memory from the OS in large chunks and does suballocation out of
  487. the chunks (class Pool implements this).  Memory freed via "delete"
  488. goes into a free list and is immediately available for allocation
  489. again via "new".  Memory is not actually freed until the "freeAll"
  490. method is called, which occurs only when the hash table is cleared.
  491. Then the large memory chunks are returned to the OS.
  492.  
  493. 6. Position Scoring
  494.  
  495. There are six main components to the positional score used by Arasan:
  496.  
  497. a. Center control
  498. b. Development
  499. c. Castling
  500. d. Pawn structure
  501. e. King safety
  502. f. Threats
  503.  
  504. The positional score is typically within the range of plus or minus
  505. the value of a pawn (64), but can be greater in some circumstances.
  506.  
  507. When in the endgame (determined by the amount of material on the board)
  508. simplified and/or different scoring parameters are used.  Also,
  509. special scoring code is used for "mopping up" positions, in which
  510. one side has a large material advantage.  Chess 4.5 from Northwestern
  511. University used a similar scheme.
  512.  
  513. Center control is mostly calculated by table lookup.  For sliding
  514. pieces, a check is made to be sure that the piece has an unobstructed
  515. line of movement to the center of the board.  This component of the
  516. score is not used in the endgame.
  517.  
  518. The development score encourages the program to move its pieces from
  519. the back rank, but discourages premature development of the queen.
  520. A measure of piece mobility is also calculated for bishops and rooks.
  521. Bonuses are awarded for a rook on the 7th rank, and also for a rook
  522. on an open or half-open file, and for doubled rooks.
  523.  
  524. In the endgame, the development score encourages the king to move
  525. towards the center or opposite side of the board, and to stay
  526. near pawns.  A bonus is also awarded for having the opposition.
  527. This code is not very effective in producing good play, but it
  528. is better than nothing.  Special-case code is included for 
  529. KPK and KNBK endgames, which enables the program to play these
  530. fairly well.
  531.  
  532. When "mopping up", the development score gives a bonus for restricting
  533. the opposing king's mobility and for driving the opposing king to
  534. an edge or corner of the board. 
  535.  
  536. The castling score penalizes the program for being unable to castle,
  537. either temporarily (because a square traversed by castling is under
  538. attack) or permanently (because the king or rook has made another move).
  539.  
  540. The pawn structure score penalizes isolated, backward, and doubled
  541. pawns, and gives a bonus for passed pawns.  If a passed pawn exists,
  542. its value depends on its rank and also on whether squares ahead of
  543. it are occupied or controlled by the opposing side.
  544.  
  545. The king safety score evaluates the extent to which the king is
  546. protected by pawns, and also the extent to which opposing pieces
  547. attack squares near the king.  It is pretty inexact, but does
  548. at least alert the side to move when the king is in serious trouble.
  549.  
  550. The threat score penalizes the side to move for having pieces
  551. that appear to be trapped or to be subject to profitable capture
  552. ("en prise").  A pinned piece is given the same penalty as a 
  553. trapped piece.  Usually the search routine will extend the search
  554. when such situations exist, but we have to do something when the
  555. terminal search depth is reached.
  556.  
  557. Contacting the Author
  558.  
  559. I have been working on computer chess programming for around seven
  560. years, and this is the second complete chess program I have written.
  561. It is still very much imperfect - but I have decided to release it
  562. in its present form, both so that others can enjoy playing with it
  563. and so that programmers can study it, learn from it, and maybe
  564. improve it.  I don't guarantee any support for this program.  However,
  565. if you do find bugs in it, or discover a way to improve it, I would
  566. like to hear from you.  I can be reached at:
  567.  
  568. Jon Dart
  569. 553 N. 17th St.
  570. San Jose, CA 95112
  571.  
  572. Or via Internet at jdart@rational.com.
  573.  
  574. References
  575.  
  576. Frey, Peter W. (ed.) (1983). Chess Skill in Man and Machine.
  577. New York: Springer-Verlag.
  578.  
  579. Marsand, T. Anthony and Schaeffer, Jonathan (1990).  Computers,
  580. Chess and Cognition. New York: Springer-Verlag.
  581.  
  582.  
  583.